﻿using System.IO;
using System.Text;

namespace VideoTools.SubtitleEdit.Common
{
    /// <summary>
    /// File related utilities.
    /// </summary>
    public static class FileUtil
    {
        /// <summary>
        /// Opens a binary file in read/write shared mode, reads the contents of the file into a
        /// byte array, and then closes the file.
        /// </summary>
        /// <param name="path">The file to open for reading. </param>
        /// <returns>A byte array containing the contents of the file.</returns>
        public static byte[] ReadAllBytesShared(string path)
        {
            using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                var index = 0;
                var fileLength = fs.Length;
                if (fileLength > int.MaxValue)
                {
                    throw new IOException("File too long");
                }

                var count = (int)fileLength;
                var bytes = new byte[count];
                while (count > 0)
                {
                    var n = fs.Read(bytes, index, count);
                    if (n == 0)
                    {
                        throw new InvalidOperationException("End of file reached before expected");
                    }

                    index += n;
                    count -= n;
                }
                return bytes;
            }
        }

        public static byte[] ReadBytesShared(string path, int bytesToRead)
        {
            using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                var index = 0;
                var fileLength = fs.Length;
                if (fileLength > int.MaxValue)
                {
                    throw new IOException("File too long");
                }

                var count = Math.Min(bytesToRead, (int)fileLength);
                var bytes = new byte[count];
                while (count > 0)
                {
                    var n = fs.Read(bytes, index, count);
                    if (n == 0)
                    {
                        throw new InvalidOperationException("End of file reached before expected");
                    }

                    index += n;
                    count -= n;
                }

                return bytes;
            }
        }

        public static List<string> ReadAllLinesShared(string path, Encoding encoding)
        {
            var bytes = ReadAllBytesShared(path);
            if (bytes.Length > 3 && Equals(encoding, Encoding.UTF8) && bytes[0] == 0xef && bytes[1] == 0xbb && bytes[2] == 0xbf)
            {
                return encoding.GetString(bytes, 3, bytes.Length - 3).SplitToLines();
            }

            if (bytes.Length > 2 && Equals(encoding, Encoding.Unicode) && bytes[0] == 0xfe && bytes[1] == 0xff)
            {
                return encoding.GetString(bytes, 2, bytes.Length - 2).SplitToLines();
            }

            return encoding.GetString(bytes).SplitToLines();
        }


    }
}
